import sublime, sublime_plugin
import time 
from threading import Thread, Lock

is_off = False #是否关闭自动保存

lock = Lock()

class SwitchAutoSaveCommand(sublime_plugin.WindowCommand):
	def run(self):
		global is_off
		is_off = not is_off
		stuta = ""
		if is_off:
			stuta = "off" 
		else:
			stuta = "on"
		sublime.status_message("auto save : " + stuta)


class Task:
	def __init__(self, _view, _modified_time):
		self.view = _view
		self.modified_time = _modified_time


class auto_save():

	def __init__(self, _instance_name):
		print("init plugin [auto_save] sublime_version:", sublime.version())
		s = sublime.load_settings("auto_save.sublime-settings")
		self.instance_name = _instance_name
		self.auto_save_delay_time = 2000
		self.sleep_time = 2
		self.task = []
		auto_save_time = s.get("auto_save_time")
		if auto_save_time:
			self.auto_save_delay_time = auto_save_time
		t = Thread(target=self.start_loop)
		t.start()

	def start_loop(self):
		while True:
			global is_off
			time.sleep(self.sleep_time)
			if is_off is True:
				continue
			now = time.time() * 1000
			for x in self.task:
				if now - x.modified_time >= self.auto_save_delay_time:
					file_name = x.view.file_name()
					if file_name == None: #新建的文件，写入了内容，但迟迟未保存
						lock.acquire()
						self.task.remove(x)
						lock.release()
						continue
					print("view " , x.view.id(), " save")
					print("file:", file_name)
					x.view.run_command("save")
					lock.acquire()
					self.task.remove(x)
					lock.release()

	def insert(self, _task):
		flag = True
		for x in self.task:
			if x.view == _task.view:
				lock.acquire()
				x.modified_time = _task.modified_time
				lock.release()
				print("view ", x.view.id(), "update_modified_time")
				flag = False
		if flag == True:
			lock.acquire()
			self.task.append(_task)
			lock.release()
			print("view ",_task.view.id(), "modified")


	def on_modified(self, view):
		#修改文件的时候sublime会自动调用此方法
		t = time.time() * 1000 #ms
		self.insert(Task(view, t))

	def on_selection_modified(self, view):
		#对文件有鼠标选中，单击事件时会调用
		t = time.time() * 1000 #ms
		for x in self.task:
			if x.view == view:
				lock.acquire()
				x.modified_time = t
				lock.release()
				print("view ", x.view.id(), "update_modified_time")
			else:
				print("no need to save")

	def on_post_save(self, view):
		print("save remove")
		for x in self.task:
			if x.view == view:
				lock.acquire()
				self.task.remove(x)
				lock.release()


code = "cmj-auto-save-instance-code"

def mount_plugin():
	#此处使用挂载的方法往sublime中添加plugin，让plugin随着sublime自启动
	g_auto_save = auto_save(code)

	for x in sublime_plugin.all_callbacks["on_modified"]:
		if hasattr(x, 'instance_name') and x.instance_name == code:
			print("already exists auto_save instance")
			sublime_plugin.all_callbacks["on_modified"].remove(x)


	print("push auto_save instance")
	sublime_plugin.all_callbacks["on_modified"].append(g_auto_save)
	
	for x in sublime_plugin.all_callbacks["on_selection_modified"]:
		if hasattr(x, 'instance_name') and x.instance_name == code:
			print("already exists auto_save instance")
			sublime_plugin.all_callbacks["on_selection_modified"].remove(x)

	sublime_plugin.all_callbacks["on_selection_modified"].append(g_auto_save)

	for x in sublime_plugin.all_callbacks["on_post_save"]:
		if hasattr(x, 'instance_name') and x.instance_name == code:
			print("already exists auto_save instance")
			sublime_plugin.all_callbacks["on_post_save"].remove(x)

	sublime_plugin.all_callbacks["on_post_save"].append(g_auto_save)
	

mount_plugin()